package com.hfzy.ihk.web.aliyuncall.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dyvmsapi.model.v20170525.CancelCallRequest;
import com.aliyuncs.dyvmsapi.model.v20170525.CancelCallResponse;
import com.aliyuncs.dyvmsapi.model.v20170525.ClickToDialRequest;
import com.aliyuncs.dyvmsapi.model.v20170525.ClickToDialResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.hfzy.ihk.common.util.CommonUtils;
import com.hfzy.ihk.common.util.date.DateUtils;
import com.hfzy.ihk.common.util.string.StringTools;
import com.hfzy.ihk.common.util.string.StringUtil;
import com.hfzy.ihk.common.util.uuid.base64uuid.UUIDs;
import com.hfzy.ihk.web.aliyuncall.biz.AliyunAsrCallStateBiz;
import com.hfzy.ihk.web.aliyuncall.biz.AliyunAsrOptBiz;
import com.hfzy.ihk.web.aliyuncall.biz.AliyunCallStateBiz;
import com.hfzy.ihk.web.aliyuncall.biz.AliyunRecordFileBiz;
import com.hfzy.ihk.web.aliyuncall.constant.*;
import com.hfzy.ihk.web.aliyuncall.support.ColudCallUtils;
import com.hfzy.ihk.web.aliyuncall.support.SampleMemoryCache;
import com.hfzy.ihk.web.aliyuncall.support.websocket.WebSocketUtils;
import com.hfzy.ihk.web.aliyuncall.vo.*;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 接收阿里云部分中间状态 http接收类
 */
@RestController
@RequestMapping("aliyunOpt")
public class AliyunOptController {


    private static  final Logger logger = LoggerFactory.getLogger(AliyunOptController.class);
    @Autowired
    RedisTemplate redisTemplate;


    @Autowired
    AliyunCallStateBiz aliyunCallStateBiz;

    @Autowired
    AliyunRecordFileBiz aliyunRecordFileBiz;

    @Autowired
    AliyunAsrCallStateBiz aliyunAsrCallStateBiz;

    @Autowired
    WebSocketUtils webSocketUtils;

    @Autowired
    ColudCallUtils coludCallUtils;


    @Autowired
    AliyunAsrOptBiz aliyunAsrOptBiz;



    /**
     * 阿里云推送呼叫中间状态接口 ，
     *
     * @return
     */
    @RequestMapping("receiveVoiceCallReport")
    public AliyunResponeVo ReceiveVoiceCallReport(HttpServletRequest request){
        String jsonData = CommonUtils.getInputStr(request);
        logger.info("中间状态："+ jsonData);
        if(StringTools.isEmpty(jsonData)){
            return  AliyunResponeVo.success();
        }
//        List<AliyunCallState> list = JSONArray.parseArray(jsonData,AliyunCallState.class);
//
//        aliyunCallStateBiz.dealCallState(list,AliyunAkInfo.VOICECALLREPORT);

        return AliyunResponeVo.success();

    }



    /**
     * 阿里云账单接口 账单要走http 因为呼入账单只有http方式有，
     * 这里的账单包括 通话的话务单，和语音识别的账单，语音识别的账单回来以后是需要发送给分析服务器的
     *
     *
     * @return
     */
    @RequestMapping("receiveVoiceReport")
    public AliyunResponeVo ReceiveVoiceReport(HttpServletRequest request){
        String jsonData = CommonUtils.getInputStr(request);
        logger.info("获取阿里云话单消息："+ jsonData);


        if(StringTools.isEmpty(jsonData)){
            return  AliyunResponeVo.success();
        }

        List<AliyunCallState> list = JSONArray.parseArray(jsonData,AliyunCallState.class);

        if(StringTools.isEmpty(list)) {
            logger.info("------->获取账单消息失败:{}",jsonData);
            return AliyunResponeVo.success();
        }
        for(AliyunCallState aliyunCallState:list){
            //判断是双呼账单还是 ASR 智能外呼账单
            String sessionId = aliyunCallState.getOut_id();

            if(StringTools.isEmpty(sessionId)){//呼入是不存在sessionID的 只能通过callId获得sessionId
                sessionId = coludCallUtils.getSessionIdByCallId(aliyunCallState.getCall_id());
                aliyunCallState.setOut_id(sessionId);
            }
            if(sessionId==null)
                continue;
            String commitTo = null;
            try {
                commitTo= coludCallUtils.getCommitTo(sessionId);
            }catch (Exception e){
                logger.info("------->账单消息获取commitTO异常:{}",jsonData,e);
            }
            if(commitTo==null){
                logger.info("呼叫中间状态未找到commitTo,msg:{}",jsonData);
                continue;

            }
            Long start = System.currentTimeMillis();

            if(commitTo.equals("12")) { //ASR智能外呼状态
                aliyunAsrCallStateBiz.dealCallState(aliyunCallState,AliyunAkInfo.VOICEREPORT);
            }else{//双呼状态
                aliyunCallStateBiz.dealCallState(aliyunCallState, AliyunAkInfo.VOICEREPORT);
            }
            logger.info("中间状态入队时间：" + (System.currentTimeMillis() - start));


        }
        return AliyunResponeVo.success();

    }
    /**
     * 阿里云推送录音接口
     * @param voiceRecordReportVo
     * @returnr
     */
    @RequestMapping("receiveVoiceRecordReport")
    public AliyunResponeVo ReceiveVoiceRecordReport(HttpServletRequest request, VoiceRecordReportVo voiceRecordReportVo){
        String jsonData = CommonUtils.getInputStr(request);
        logger.info("获取录音url："+ jsonData);


        if(StringTools.isEmpty(jsonData)){
            return  AliyunResponeVo.success();
        }

        List<AliyunRecordFile> list = JSONArray.parseArray(jsonData,AliyunRecordFile.class);
        aliyunRecordFileBiz.dealCallState(list);
        return AliyunResponeVo.success();

    }

    /**
     * 阿里云推送实时语音识别接口 语音也是只有http方式有
     * @param VoiceRTASRReportVo
     * @returnr
     */
    @RequestMapping("receiveVoiceRTASRReport")
    public AliyunResponeVo ReceiveVoiceRTASRReport(HttpServletRequest request, VoiceRTASRReportVo VoiceRTASRReportVo){

        String jsonData = CommonUtils.getInputStr(request);
        logger.info("实时语音："+ jsonData);


        if(StringTools.isEmpty(jsonData)){
            return  AliyunResponeVo.success();
        }

//        List<VoiceRTASRReportVo> list = JSONArray.parseArray(jsonData,VoiceRTASRReportVo.class);
//        list.sort((o1,o2)->o1.getBegin_offset().compareTo(o2.getBegin_offset()));
//        for(VoiceRTASRReportVo voiceRTASRReportVo:list){
//            webSocketUtils.pushToClientBySessionId(voiceRTASRReportVo.getOut_id(),JSONObject.toJSONString(voiceRTASRReportVo));
//        }
        //通过rmi推送过去，做测试

        return AliyunResponeVo.success();

    }

    /**
     * 智能外呼ASR实时交互
     /**
     *
     * @param content 客户说的话被识别的内容 ：{"role":"B","identity":"id2","robot_id":null,"current_media_code":"08a0e68a-9fbe-40b8-a8c5-335af67d89b3.wav","dynamic_id":null,"action_code_break":"true","words":"喂你好","is_playing":"true","end_offset":"1640","begin_time":"1539769430","begin_offset":"430","node_id":null}
     * @param call_id 业务id
     * @param timestamp  当前时间戳
     * @param content_type 消息类型normal、mute(静音) 可以利用这个来判断是否是静音消息
     * @return
     */
    @RequestMapping("receiveVoiceAndRTASRReport")
    public AliyunAsrResponeVo ReceiveVoiceAndRTASRReport(String content,String call_id,String timestamp,String content_type){
        if(content_type==null&&call_id==null){//配置测试消息直接返回成功
            return AliyunAsrResponeVo.getTestMsg();
        }

        logger.info("阿里云ASR 外呼回调call_id：{},timestamp:{},content_type:{},content:{}",call_id,timestamp,content_type,content);
            AliyunAsrResponeVo aliyunAsrResponeVo =
                    aliyunAsrOptBiz.AsrOpt(content, call_id, content_type);

        return aliyunAsrResponeVo;
    }


    /**
     * 呼入转接
     * @param vo
     * @return
     */
    @RequestMapping("/dynamicTrans")
    public Map<String,Object> dynamicTransNum(AliyunTransNumVo vo){
        Map<String,Object> map = new HashMap<>();
        Map<String,Object> dataMap = new HashMap<>();


        if(StringTools.isEmpty(vo.getCaller_num())
                ||StringTools.isEmpty(vo.getCaller_show_num())
                ||StringTools.isEmpty(vo.getCall_id())){
            map.put("result", Constants.FAIL_STR);
            map.put("msg","缺少必要参数！");
            map.put("data",dataMap);
            return map;
        }

        try {
            String sessionId = UUIDs.base64UUID();
            vo.setSessionId(sessionId);

            vo.setCalled_show_num("057128204523");
            dataMap.put("called_num", "13418035053");
            dataMap.put("called_show_num", "057128204523");
            dataMap.put("call_id", StringTools.isEmpty(vo.getCall_id()) ? "" : vo.getCall_id());


        }catch (Exception e){
            logger.error("呼入获取主显号异常，callId:{}",vo.getCall_id(),e);
            dataMap.put("called_num", "-1");
        }finally {
            map.put("result", Constants.SUCCESS_STR);
            map.put("msg", "成功");
            map.put("data", dataMap);
        }

        return map;
    }

}
